Closed Bug 1873802 Opened 1 year ago Closed 1 year ago

Assertion failure: aValue.isFinite() && minimum.isFinite() && maximum.isFinite() (type=range should have a default maximum/minimum), at /builds/worker/checkouts/gecko/layout/forms/nsRangeFrame.cpp:328

Categories

(Core :: Layout: Form Controls, defect)

defect

Tracking

()

VERIFIED FIXED
123 Branch
Tracking Status
firefox-esr115 --- wontfix
firefox121 --- wontfix
firefox122 --- wontfix
firefox123 --- verified

People

(Reporter: tsmith, Assigned: dholbert)

References

(Blocks 1 open bug)

Details

(4 keywords, Whiteboard: [bugmon:bisected,confirmed])

Attachments

(2 files)

Attached file testcase.html

Found while fuzzing m-c 20231113-211dc86c8f53 (--enable-debug --enable-fuzzing)

To reproduce via Grizzly Replay:

$ pip install fuzzfetch grizzly-framework
$ python -m fuzzfetch -d --fuzzing -n firefox
$ python -m grizzly.replay.bugzilla ./firefox/firefox <bugid>

Assertion failure: aValue.isFinite() && minimum.isFinite() && maximum.isFinite() (type=range should have a default maximum/minimum), at /builds/worker/checkouts/gecko/layout/forms/nsRangeFrame.cpp:328

#0 0x7fc1e8664aa9 in nsRangeFrame::GetDoubleAsFractionOfRange(blink::Decimal const&) /builds/worker/checkouts/gecko/layout/forms/nsRangeFrame.cpp:327:3
#1 0x7fc1e866423e in GetValueAsFractionOfRange /builds/worker/checkouts/gecko/layout/forms/nsRangeFrame.cpp:318:10
#2 0x7fc1e866423e in nsRangeFrame::DoUpdateThumbPosition(nsIFrame*, nsSize const&) /builds/worker/checkouts/gecko/layout/forms/nsRangeFrame.cpp:550:21
#3 0x7fc1e8663a68 in nsRangeFrame::ReflowAnonymousContent(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&) /builds/worker/checkouts/gecko/layout/forms/nsRangeFrame.cpp:280:5
#4 0x7fc1e8662c1b in nsRangeFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/forms/nsRangeFrame.cpp:179:3
#5 0x7fc1e85d7c85 in nsLineLayout::ReflowFrame(nsIFrame*, nsReflowStatus&, mozilla::ReflowOutput*, bool&) /builds/worker/checkouts/gecko/layout/generic/nsLineLayout.cpp:891:13
#6 0x7fc1e84bea3f in nsBlockFrame::ReflowInlineFrame(mozilla::BlockReflowState&, nsLineLayout&, nsLineList_iterator, nsIFrame*, LineReflowStatus*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:4998:15
#7 0x7fc1e84bdc39 in nsBlockFrame::DoReflowInlineFrames(mozilla::BlockReflowState&, nsLineLayout&, nsLineList_iterator, nsFlowAreaRect&, int&, nsFloatManager::SavedState*, bool*, LineReflowStatus*, bool) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:4800:5
#8 0x7fc1e84b9b39 in nsBlockFrame::ReflowInlineFrames(mozilla::BlockReflowState&, nsLineList_iterator, bool*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:4674:9
#9 0x7fc1e84b5f54 in nsBlockFrame::ReflowLine(mozilla::BlockReflowState&, nsLineList_iterator, bool*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:3646:5
#10 0x7fc1e84b0bc1 in nsBlockFrame::ReflowDirtyLines(mozilla::BlockReflowState&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:3156:9
#11 0x7fc1e84ad9ab in nsBlockFrame::TrialReflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsBlockFrame::TrialReflowState&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:1906:3
#12 0x7fc1e84abadf in nsBlockFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:1552:9
#13 0x7fc1e84bc959 in nsBlockReflowContext::ReflowBlock(mozilla::LogicalRect const&, bool, nsCollapsingMargin&, int, nsLineBox*, mozilla::ReflowInput&, nsReflowStatus&, mozilla::BlockReflowState&) /builds/worker/checkouts/gecko/layout/generic/nsBlockReflowContext.cpp:290:11
#14 0x7fc1e84b8790 in nsBlockFrame::ReflowBlockFrame(mozilla::BlockReflowState&, nsLineList_iterator, bool*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:4311:11
#15 0x7fc1e84b6006 in nsBlockFrame::ReflowLine(mozilla::BlockReflowState&, nsLineList_iterator, bool*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:3643:5
#16 0x7fc1e84b0bc1 in nsBlockFrame::ReflowDirtyLines(mozilla::BlockReflowState&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:3156:9
#17 0x7fc1e84ad9ab in nsBlockFrame::TrialReflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsBlockFrame::TrialReflowState&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:1906:3
#18 0x7fc1e84abadf in nsBlockFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:1552:9
#19 0x7fc1e84e0c04 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, mozilla::WritingMode const&, mozilla::LogicalPoint const&, nsSize const&, nsIFrame::ReflowChildFlags, nsReflowStatus&, nsOverflowContinuationTracker*) /builds/worker/checkouts/gecko/layout/generic/nsContainerFrame.cpp:887:14
#20 0x7fc1e84cebab in nsCanvasFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/generic/nsCanvasFrame.cpp:760:7
#21 0x7fc1e84e0c04 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, mozilla::WritingMode const&, mozilla::LogicalPoint const&, nsSize const&, nsIFrame::ReflowChildFlags, nsReflowStatus&, nsOverflowContinuationTracker*) /builds/worker/checkouts/gecko/layout/generic/nsContainerFrame.cpp:887:14
#22 0x7fc1e8526d75 in nsHTMLScrollFrame::ReflowScrolledFrame(mozilla::ScrollReflowInput&, bool, bool, mozilla::ReflowOutput*) /builds/worker/checkouts/gecko/layout/generic/nsGfxScrollFrame.cpp:938:3
#23 0x7fc1e8527b2e in nsHTMLScrollFrame::ReflowContents(mozilla::ScrollReflowInput&, mozilla::ReflowOutput const&) /builds/worker/checkouts/gecko/layout/generic/nsGfxScrollFrame.cpp:1071:3
#24 0x7fc1e852c7ac in nsHTMLScrollFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/generic/nsGfxScrollFrame.cpp:1508:3
#25 0x7fc1e84e10f1 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, int, int, nsIFrame::ReflowChildFlags, nsReflowStatus&, nsOverflowContinuationTracker*) /builds/worker/checkouts/gecko/layout/generic/nsContainerFrame.cpp:928:14
#26 0x7fc1e84a1ac2 in mozilla::ViewportFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/generic/ViewportFrame.cpp:379:7
#27 0x7fc1e838a494 in mozilla::PresShell::DoReflow(nsIFrame*, bool, mozilla::OverflowChangedTracker*) /builds/worker/checkouts/gecko/layout/base/PresShell.cpp:9697:11
#28 0x7fc1e83b39cf in mozilla::PresShell::ProcessReflowCommands(bool) /builds/worker/checkouts/gecko/layout/base/PresShell.cpp:9870:22
#29 0x7fc1e8394943 in DoFlushLayout /builds/worker/checkouts/gecko/layout/base/PresShell.cpp:9941:10
#30 0x7fc1e8394943 in mozilla::PresShell::DoFlushPendingNotifications(mozilla::ChangesToFlush) /builds/worker/checkouts/gecko/layout/base/PresShell.cpp:4351:11
#31 0x7fc1e46c5def in FlushPendingNotifications /builds/worker/workspace/obj-build/dist/include/mozilla/PresShell.h:1474:5
#32 0x7fc1e46c5def in mozilla::dom::Document::FlushPendingNotifications(mozilla::ChangesToFlush) /builds/worker/checkouts/gecko/dom/base/Document.cpp:10891:16
#33 0x7fc1e46c5cc6 in mozilla::dom::Document::FlushPendingNotifications(mozilla::ChangesToFlush) /builds/worker/checkouts/gecko/dom/base/Document.cpp:10887:22
#34 0x7fc1e84cac0b in InsertAnonymousContentInContainer(mozilla::dom::Document&, mozilla::dom::Element&) /builds/worker/checkouts/gecko/layout/generic/nsCanvasFrame.cpp:107:8
#35 0x7fc1e84d7c4d in operator() /builds/worker/checkouts/gecko/layout/generic/nsCanvasFrame.cpp:157:11
#36 0x7fc1e84d7c4d in mozilla::detail::RunnableFunction<nsCanvasFrame::CreateAnonymousContent(nsTArray<nsIAnonymousContentCreator::ContentInfo>&)::$_0>::Run() /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:548:5
#37 0x7fc1e445572e in nsContentUtils::RemoveScriptBlocker() /builds/worker/checkouts/gecko/dom/base/nsContentUtils.cpp:6130:17
#38 0x7fc1e841904d in ~nsAutoScriptBlocker /builds/worker/workspace/obj-build/dist/include/nsContentUtils.h:3693:28
#39 0x7fc1e841904d in nsDocumentViewer::Show() /builds/worker/checkouts/gecko/layout/base/nsDocumentViewer.cpp:2141:3
#40 0x7fc1e96b1ef6 in nsDocShell::SetVisibility(bool) /builds/worker/checkouts/gecko/docshell/base/nsDocShell.cpp
#41 0x7fc1e492b4a0 in nsFrameLoader::Show(nsSubDocumentFrame*) /builds/worker/checkouts/gecko/dom/base/nsFrameLoader.cpp:1012:15
#42 0x7fc1e85fd887 in nsSubDocumentFrame::ShowViewer() /builds/worker/checkouts/gecko/layout/generic/nsSubDocumentFrame.cpp:202:38
#43 0x7fc1e8638bc4 in AsyncFrameInit::Run() /builds/worker/checkouts/gecko/layout/generic/nsSubDocumentFrame.cpp:110:60
#44 0x7fc1e445572e in nsContentUtils::RemoveScriptBlocker() /builds/worker/checkouts/gecko/dom/base/nsContentUtils.cpp:6130:17
#45 0x7fc1e83948ae in ~nsAutoScriptBlocker /builds/worker/checkouts/gecko/dom/base/nsContentUtils.h:3693:28
#46 0x7fc1e83948ae in mozilla::PresShell::DoFlushPendingNotifications(mozilla::ChangesToFlush) /builds/worker/checkouts/gecko/layout/base/PresShell.cpp:4336:5
#47 0x7fc1e8358f89 in FlushPendingNotifications /builds/worker/workspace/obj-build/dist/include/mozilla/PresShell.h:1474:5
#48 0x7fc1e8358f89 in nsRefreshDriver::TickObserverArray(unsigned int, mozilla::TimeStamp) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:2502:20
#49 0x7fc1e8355958 in nsRefreshDriver::Tick(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp, nsRefreshDriver::IsExtraTick) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:2736:28
#50 0x7fc1e835f2f1 in TickDriver /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:367:13
#51 0x7fc1e835f2f1 in mozilla::RefreshDriverTimer::TickRefreshDrivers(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp, nsTArray<RefPtr<nsRefreshDriver>>&) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:345:7
#52 0x7fc1e835f1f0 in mozilla::RefreshDriverTimer::Tick(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:361:5
#53 0x7fc1e835f08d in mozilla::VsyncRefreshDriverTimer::RunRefreshDrivers(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:951:5
#54 0x7fc1e835e32c in mozilla::VsyncRefreshDriverTimer::TickRefreshDriver(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp) /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:861:5
#55 0x7fc1e835d599 in mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::NotifyVsyncTimerOnMainThread() /builds/worker/checkouts/gecko/layout/base/nsRefreshDriver.cpp:592:14
#56 0x7fc1e7687b9b in mozilla::dom::VsyncMainChild::RecvNotify(mozilla::VsyncEvent const&, float const&) /builds/worker/checkouts/gecko/dom/ipc/VsyncMainChild.cpp:66:15
#57 0x7fc1e7973fcd in mozilla::dom::PVsyncChild::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PVsyncChild.cpp:227:78
#58 0x7fc1e7860110 in mozilla::dom::PContentChild::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PContentChild.cpp:8264:32
#59 0x7fc1e373c07f in mozilla::ipc::MessageChannel::DispatchAsyncMessage(mozilla::ipc::ActorLifecycleProxy*, IPC::Message const&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1813:25
#60 0x7fc1e3738dd2 in mozilla::ipc::MessageChannel::DispatchMessage(mozilla::ipc::ActorLifecycleProxy*, mozilla::UniquePtr<IPC::Message, mozilla::DefaultDelete<IPC::Message>>) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1732:9
#61 0x7fc1e3739a52 in mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::ActorLifecycleProxy*, mozilla::ipc::MessageChannel::MessageTask&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1525:3
#62 0x7fc1e373ab9f in mozilla::ipc::MessageChannel::MessageTask::Run() /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1623:14
#63 0x7fc1e2a4dd67 in mozilla::RunnableTask::Run() /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:568:16
#64 0x7fc1e2a434d6 in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:895:26
#65 0x7fc1e2a41cb7 in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:718:15
#66 0x7fc1e2a42135 in mozilla::TaskController::ProcessPendingMTTask(bool) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:504:36
#67 0x7fc1e2a51d06 in operator() /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:222:37
#68 0x7fc1e2a51d06 in mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::$_0>::Run() /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.h:548:5
#69 0x7fc1e2a67072 in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:1199:16
#70 0x7fc1e2a6e1bd in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:480:10
#71 0x7fc1e3741fe5 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:85:21
#72 0x7fc1e365b6b1 in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:363:3
#73 0x7fc1e365b6b1 in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:345:3
#74 0x7fc1e7f92748 in nsBaseAppShell::Run() /builds/worker/checkouts/gecko/widget/nsBaseAppShell.cpp:148:27
#75 0x7fc1e804f698 in nsAppShell::Run() /builds/worker/checkouts/gecko/widget/gtk/nsAppShell.cpp:470:33
#76 0x7fc1e9e9a04b in XRE_RunAppShell() /builds/worker/checkouts/gecko/toolkit/xre/nsEmbedFunctions.cpp:721:20
#77 0x7fc1e3742ec6 in mozilla::ipc::MessagePumpForChildProcess::Run(base::MessagePump::Delegate*) /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:235:9
#78 0x7fc1e365b6b1 in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:363:3
#79 0x7fc1e365b6b1 in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:345:3
#80 0x7fc1e9e998b2 in XRE_InitChildProcess(int, char**, XREChildData const*) /builds/worker/checkouts/gecko/toolkit/xre/nsEmbedFunctions.cpp:656:34
#81 0x557c51a35156 in content_process_main /builds/worker/checkouts/gecko/browser/app/../../ipc/contentproc/plugin-container.cpp:57:28
#82 0x557c51a35156 in main /builds/worker/checkouts/gecko/browser/app/nsBrowserApp.cpp:375:18
#83 0x7fc1f8429d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#84 0x7fc1f8429e3f in __libc_start_main csu/../csu/libc-start.c:392:3
#85 0x557c51a0ae88 in _start (/home/user/workspace/browsers/m-c-20240109162901-fuzzing-debug/firefox-bin+0x58e88) (BuildId: e4c62efaf5851b0d60578cde9670049ea317e982)
Component: Graphics → Layout: Form Controls

Verified bug as reproducible on mozilla-central 20240110045147-33d47d05c368.
The bug appears to have been introduced in the following build range:

Start: bdd4883cb9aff011cf3435955371f8d3f2c32c97 (20230111232021)
End: 43b22535b4a2547faadb44e2aff9401a9bcca4f3 (20230112030245)
Pushlog: https://hg.mozilla.org/integration/autoland/pushloghtml?fromchange=bdd4883cb9aff011cf3435955371f8d3f2c32c97&tochange=43b22535b4a2547faadb44e2aff9401a9bcca4f3

Keywords: regression
Whiteboard: [bugmon:bisected,confirmed]

:alaskanemily could this have been when css named pages was enabled in 110 in bug 1802239?

Flags: needinfo?(emcdonough)

Unlikely to be that; that css-named-pages pref-flip would only make a difference if the testcase used the page: ... CSS property and triggered print-preview, and it seems to do neither.

From quick skim of regression range, I'd suspect maybe bug 1808824 or bug 1809749 might be involved, though they may've just made it easier to trigger a preexisting issue.

Let's get a pernosco trace.

Keywords: pernosco-wanted
Flags: needinfo?(emcdonough)

I can reproduce the assert locally, and I confirmed that reverting the content.sink.perf_parse_time pref-tweak from bug 1808824 makes the issue go away.

That doesn't mean there's a problem with bug 1808824; it just means that we have a bug that gets papered-over when we let this testcase parse-to-completion before we attempt to lay it out (if I'm understanding content.sink.perf_parse_time properly).

So this is superficially a regression from bug 1808824, but really this is probably possible to trigger in older builds, and it would just require a different testcase to trigger there (which would append some of the DOM dynamically instead of having it inline, or be substantially larger so as to overshoot the larger content.sink.perf_parse_time, or something else.)

Successfully recorded a pernosco session. A link to the pernosco session will be added here shortly.

A pernosco session for this bug can be found here.

So, quoting the assertion:
(In reply to Tyson Smith [:tsmith] from comment #0)

Assertion failure: aValue.isFinite() && minimum.isFinite() && maximum.isFinite() (type=range should have a default maximum/minimum), at /builds/worker/checkouts/gecko/layout/forms/nsRangeFrame.cpp:328

Pernosco shows that we're failing the first part, aValue.isFinite(), because aValue here is in fact NaN. That seems to be what naturally happens when our HTMLInputElement has the empty string as its value, base on how HTMLInputElement::GetValueAsDecimal works.

In a local testcase with just <input type="range">, we don't hit this issue, because the HTMLInputElement ends up getting a value of "50" automatically established before we reach nsRangeFrame::GetDoubleAsFractionOfRange. That happens via this backtrace when we're setting its value to the empty string:

#0  mozilla::dom::HTMLInputElement::SanitizeValue(nsTSubstring<char16_t>&, mozilla::dom::HTMLInputElement::SanitizationKind) const (this=0x7fa646005200, aValue=<gNullChar> u"", aKind=mozilla::dom::HTMLInputElement::SanitizationKind::ForValueSetter) at /scratch/work/builds/mozilla-central/mozilla/dom/html/HTMLInputElement.cpp:4848
#1  0x00007fa65b971717 in mozilla::dom::HTMLInputElement::SetValueInternal(nsTSubstring<char16_t> const&, nsTSubstring<char16_t> const*, mozilla::EnumSet<mozilla::TextControlState::ValueSetterOption, unsigned int> const&) (this=0x7fa646005200, aValue=<gNullChar> u"", aOldValue=0x0, aOptions=const mozilla::dom::HTMLInputElement::ValueSetterOptions & = {...}) at /scratch/work/builds/mozilla-central/mozilla/dom/html/HTMLInputElement.cpp:2714
#2  0x00007fa65b98f409 in mozilla::dom::HTMLInputElement::SetValueInternal(nsTSubstring<char16_t> const&, mozilla::EnumSet<mozilla::TextControlState::ValueSetterOption, unsigned int> const&) (this=0x7fa646005200, aValue=<gNullChar> u"", aOptions=const mozilla::dom::HTMLInputElement::ValueSetterOptions & = {...}) at /scratch/work/builds/mozilla-central/obj-debug/dist/include/mozilla/dom/HTMLInputElement.h:940
#3  0x00007fa65b96bd8b in mozilla::dom::HTMLInputElement::DoneCreatingElement() (this=0x7fa646005200) at /scratch/work/builds/mozilla-central/mozilla/dom/html/HTMLInputElement.cpp:6195
#4  0x00007fa6583171e9 in nsHtml5TreeOperation::DoneCreatingElement(nsIContent*) (aNode=0x7fa646005200) at /scratch/work/builds/mozilla-central/mozilla/parser/html/nsHtml5TreeOperation.cpp:731
(More stack frames follow...)

Normally, the SanitizeValue section for SanitizeValue there notices that the empty aValue produces NaN for Decimal value there, and opts to Set value to midway between minimum and maximum which is how we end up at 50.

But with the attached fuzzer testcase, that must not happen for some reason...

Aha, so in the pernosco run, we skip over the SanitizeValue (and hence we're left with the empty-string as the value, instead of settling on 50 via the normal callstack in comment 7), because mDoneCreating is false when we get here:
https://searchfox.org/mozilla-central/rev/961a9e56a0b5fa96ceef22c61c5e75fb6ba53395/dom/html/HTMLInputElement.cpp#2706-2714

...because the parser hasn't called DoneCreatingElement yet. And in fact we do a layout and reach nsRangeFrame::Reflow while input.mDoneCreating is false. So that's why we end up seeing this "unsanitized" attribute-value.

(I'm not sure offhand if it's expected that we can reach layout for an element whose DoneCreatingElement() API hasn't been called yet... If that's expected, then we need to be able to handle this gracefully, probably by making nsRangeFrame gracefully bail instead of failing this assertion. If it's unexpected, then we need to find out why that's happening here and prevent it.)

(In reply to Daniel Holbert [:dholbert] from comment #8)

(I'm not sure offhand if it's expected that we can reach layout for an element whose DoneCreatingElement() API hasn't been called yet... If that's expected, then we need to be able to handle this gracefully, probably by making nsRangeFrame gracefully bail instead of failing this assertion. If it's unexpected, then we need to find out why that's happening here and prevent it.)

It looks like the element creation, attribute setting, and DoneCreatingElement are all distinct parser operations (as performed in nsHtml5TreeOpExecutor::RunFlushLoop until nsContentSink::DidProcessATokenImpl tells us the parser has been interrupted and we should return to the main loop).

So, it looks like it is possible/fine for the parser to yield and for frames to be constructed using an element that hasn't had DoneCreatingElement called on it yet. So we should be sure we can handle that case here.

I'm going to attach a patch that exposes whether DoneCreatingElement was called yet (and hence whether we should expect that the value has been sanitized); and if it hasn't been called, we shouldn't trust the numeric values that we get back from the element.

Assignee: nobody → dholbert
Status: NEW → ASSIGNED

Some context:

  • Our HTML parser treats element creation, attribute-parsing, and
    "DoneCreatingElement"-calls as being separate operations, and it can yield
    between them.
  • HTMLInputElement doesn't sanitize its values until DoneCreatingElement has
    been called, presumably sanitization itself depends on values (e.g. min/max)
    that might not have been parsed yet.
  • So if the HTML parser yields at just the right point (before
    DoneCreatingElement), then we might generate and reflow a nsRangeFrame whose
    underlying values (on the element) haven't yet been sanitized.

This patch handles this situation by exposing a getter to tell us whether
DoneCreatingElement has been called. If that getter returns false, we assume
that value-sanitization hasn't happened, and we disregard the element's
(presumed-to-be-unsanitized) numeric values when determining the
range's thumb-position.

Severity: -- → S3

Based on comment #1, this bug contains a bisection range found by bugmon. However, the Regressed by field is still not filled.

:dholbert, if possible, could you fill the Regressed by field and investigate this regression?

For more information, please visit BugBot documentation.

Flags: needinfo?(dholbert)

(In reply to BugBot [:suhaib / :marco/ :calixte] from comment #11)

Based on comment #1, this bug contains a bisection range found by bugmon. However, the Regressed by field is still not filled.

It's not exactly a regression, per comment 4. The regression range above is for a pref-change which caused this testcase to started asserting, but the bug goes back further than that (in debug builds) if you set the pref manually, and it's likely that other (probably larger) testcases would've asserted in a default pref configuration further-back as well.

Flags: needinfo?(dholbert)
Pushed by dholbert@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/a826f227dea1 Make nsRangeFrame place the thumb at the minimum position if it happens to get reflowed before its element is done being created. r=emilio
Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 123 Branch

Verified bug as fixed on rev mozilla-central 20240117040825-2a7dd75d1bfc.
Removing bugmon keyword as no further action possible. Please review the bug and re-add the keyword for further analysis.

Status: RESOLVED → VERIFIED
Keywords: bugmon
Flags: in-testsuite+
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: